﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Runtime.Serialization;
using System;
using System.Reflection;

namespace BrainTechLLC.ThreadSafeObjects
{
    /// <summary>
    /// Provides a global class to cache any object
    /// Care must be taken not to have code that accidentally uses the same cache object keys
    /// </summary>
	public static class StaticCache
	{
		public static ThreadSafeLookup<string, CachedObject> _cachedObjects = new ThreadSafeLookup<string, CachedObject>();

        /// <summary>
        /// Marks a cache object dirty (by key)
        /// </summary>
        /// <param name="key"></param>
		public static void MarkDirty(string key)
		{
			CachedObject c = _cachedObjects[key];

			if (c != null)
			{
				c.Dirty = true;
			}
		}        

        /// <summary>
        /// Gets the value of an object cached by string key.
        /// If the object is not in cache or is dirty, runs populateCacheDelegate to get its value and repopulate the cache for the object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="populateCacheDelegate"></param>
        /// <returns></returns>
		public static T GetValue<T>(string key, Func<T> populateCacheDelegate)
		{
			CachedObject c = _cachedObjects[key];
			if (c == null)
			{
				c = new CachedObject();
				c.Obj = populateCacheDelegate();
				_cachedObjects.AddOrSet(key, c);
				return (T)c.Obj;
			}
			else if (c.Dirty)
			{
				c.Obj = populateCacheDelegate();
				c.Dirty = false;
				return (T)c.Obj;
			}
			else
			{
				return (T)c.Obj;
			}
		}
	}
}
